home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TeX 1995 July
/
TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO
/
macros
/
latex209
/
contrib
/
vdm
/
vdm.sty
(
.txt
)
< prev
next >
Wrap
LaTeX Document
|
1993-11-07
|
44KB
|
1,128 lines
%%% ====================================================================
%%% @LaTeX-style-file{
%%% author = "Mario Wolczko",
%%% version = "3.01",
%%% date = "21 May 1992",
%%% time = "21:05:48 BST",
%%% filename = "vdm.sty",
%%% address = "Dept of Computer Science
%%% The University of Manchester
%%% Oxford Road
%%% Manchester M13 9PL
%%% UK",
%%% telephone = "+44-61-275-6146",
%%% FAX = "+44-61-275-6236",
%%% checksum = "32169 1413 3689 43831",
%%% email = "mario@cs.man.ac.uk (Internet)",
%%% codetable = "ISO/ASCII",
%%% keywords = "LaTeX, VDM specification language",
%%% supported = "yes",
%%% docstring = "LaTeX macros for typesetting VDM
%%% specifications.",
%%% }
%%% ====================================================================
% BSI VDM documentstyle option for LaTeX
% M. Wolczko
% Last edited: Thu May 21 21:05:52 1992 by mario (Mario Wolczko) on madarch
% Dept. of Computer Science Internet: mario@cs.man.ac.uk
% The University uucp: mcsun!uknet!man.cs!mario
% Manchester M13 9PL JANET: mario@uk.ac.man.cs
% U.K. Tel: +44-61-275 6146 (FAX: 6236)
% Can use either the AMS ms[ab]m fonts or the MoreMath font if
% available: follow the instructions near the string FONT-CUSTOMIZING.
%----------------------------------------------------------------
% Installation-dependent features
\let\vdm\relax % signal to ps-amsfonts
\newif\ifams@% use AMS fonts?
\newif\ifps@ % PostScript-based?
\newif\ifmoremath@ % use MoreMath font?
\newif\ifnfss@ % NFSS?
% NFSS code is enabled if \selectfont is defined;
% this is the usual test for the nfss.
\ifx\selectfont\@undefined
\global\nfss@false
\else
\global\nfss@true
\ifnfss@
% This is a patch for an NFSS bug, from Frank Mittelbach.
% It applies to the versions of lfonts.new of NFSS up to
%\def\fileversion{v1.3a}
%\def\filedate{91/11/27}
%\def\docdate {90/01/28}
\def\extract@alph@from@version#1#2{%
% #1 = alph id (cs)
% #2 = version (string)
\expandafter\extract@alph@from@version@\expandafter
#1\csname mv@#2\endcsname}
\def\extract@alph@from@version@#1#2{%
% #1 = alph id (cs)
% #2 = version (cs)
\def\extract@help##1\gdef#1##2##3\@nil{%
\def\@tempa####1{\gdef#2{##1####1##3}}%
\def\content@part{##2}}%
\expandafter\extract@help#2\@nil
\def\extract@group@no@etc\select@group#1##1##2##3\@nil{%
% ##1 group no
% ##2 extra part
% ##3 fam/ser/sha
\@tempa{%
\getanddefine@fonts{##1}##3%
\gdef#1{\use@mathgroup##2{##1}}}}%
\expandafter\extract@group@no@etc\content@part\@nil}
\def\select@group#1#2#3#4{\relax \ifmmode
\begingroup
\let \math@fonts \@empty
\escapechar \m@ne
\getanddefine@fonts #2#4%
\globaldefs \@ne
\math@fonts
\endgroup
\gdef #1{\use@mathgroup #3{#2}}%
\expandafter\extract@alph@from@version
\expandafter#1\expandafter{\math@version}%
\expandafter #1\fi }
\def\@fmtname{lplain}
\def\@psfmtname{pslplain}
\def\@testcmsy{\if@usecmsy \else
\@latexerr{Can't use vdm with this PSLaTeX}%
{This PSLaTeX does not have the CMSY symbols
available, and cannot be used with VDM style. Get
a guru to rebuild PSLaTeX with the CMSY and CMMI
fonts included.}\fi}
\def\@testcmmi{\if@usecmmi \else
\@latexerr{Can't use vdm with this PSLaTeX}%
{This PSLaTeX does not have the CMMI symbols
available, and cannot be used with VDM style. Get
a guru to rebuild PSLaTeX with the CMSY and CMMI
fonts included.}\fi}
\global\ps@false
\ifx\fmtname\@psfmtname
\global\ps@true \@testcmsy \@testcmmi
% FONT-CUSTOMIZING
% Decide under which conditions, you want to use which fonts.
% You need to set either ams@true or ams@false, and either moremath@true or
% moremath@false.
% If in doubt, set both to false.
% This uses moremath if pslatex/NFSS is in use , AMS fonts otherwise.
\global\moremath@false \global\ams@true
\ifps@
\ifnfss@ \global\moremath@true \global\ams@false \fi
\else\ifx\fmtname\@fmtname
\else \global\ams@false % don't use AMS for SliTeX
\fi\fi
\ifnfss@
\ifams@
% Firstly we call amsfonts.sty to load the AMS fonts for us.
\ifps@
\input ps-amsfonts.sty
\else
\input amsfonts.sty
\fi
\edef\msx@{\hexnumber@\msa@group}
\edef\msy@{\hexnumber@\msb@group}
\else\ifmoremath@
\new@mathgroup\mm@group
\define@mathgroup\mv@normal\mm@group{mm}{m}{n}
\edef\mm@{\hexnumber@\mm@group}
% FONT-CUSTOMIZING
% substitute correct name of MoreMath font here
\new@fontshape{mm}{m}{n}{%
<5>pmmr at5pt%
<6>pmmr at6pt%
<7>pmmr at7pt%
<8>pmmr at8pt%
<9>pmmr at9pt%
<10>pmmr at10pt%
<11>pmmr at10.95pt%
<12>pmmr at12pt%
<14>pmmr at14.4pt%
<17>pmmr at17.28pt%
<20>pmmr at20.74pt%
<25>pmmr at24.88pt}{}
\extra@def{mm}{}{}
\fi\fi
% \itfam is only defined if oldlfonts is in force, so if it is not defined,
% define it.
\ifx\itfam\@undefined
\new@mathgroup\itfam
\ifps@
\new@internalmathalphabet\mathit\itfam{times}{m}{it}
\else
\new@internalmathalphabet\mathit\itfam{cmr}{m}{it}
\fi
\fi
\ifx\math@bgroup\@empty
% nomargid synatax, \mathit will just switch the \fam if the font is
% already loaded, but will load the font the first time.
\def\vdm@it{\mathit}
\else
% margid syntax, as for nomargid, but here the scope of \mathit is its
% argument, so we call it with a null argument to make sure the font is
% loaded, then switch \fam in the old way.
\def\vdm@it{\mathit{}\fam\itfam}
\fi
\else
\ifams@
% kludges for \newfam necessary because it's \outer
\csname newfam\endcsname\msxfam
\csname newfam\endcsname\msyfam
% this is lifted from amssymbols.sty
\ifcase\@ptsize
\font\tenmsx=msam10
\font\sevenmsx=msam7
\font\fivemsx=msam5
\font\tenmsy=msbm10
\font\sevenmsy=msbm7
\font\fivemsy=msbm5
\font\tenmsx=msam10 scaled \magstephalf
\font\sevenmsx=msam8
\font\fivemsx=msam5 scaled \magstephalf
\font\tenmsy=msbm10 scaled \magstephalf
\font\sevenmsy=msbm8
\font\fivemsy=msbm5 scaled \magstephalf
\font\tenmsx=msam10 scaled \magstep1
\font\sevenmsx=msam8
\font\fivemsx=msam5 scaled \magstephalf
\font\tenmsy=msbm10 scaled \magstep1
\font\sevenmsy=msbm8
\font\fivemsy=msbm5 scaled \magstephalf
\textfont\msxfam=\tenmsx \scriptfont\msxfam=\sevenmsx
\scriptscriptfont\msxfam=\fivemsx
\textfont\msyfam=\tenmsy \scriptfont\msyfam=\sevenmsy
\scriptscriptfont\msyfam=\fivemsy
\def\hexnumber@#1{\ifnum#1<10 \number#1\else
\ifnum#1=10 A\else\ifnum#1=11 B\else\ifnum#1=12 C\else
\ifnum#1=13 D\else\ifnum#1=14 E\else
\ifnum#1=15 F\fi\fi\fi\fi\fi\fi\fi}
\def\msx@{\hexnumber@\msxfam}
\def\msy@{\hexnumber@\msyfam}
\else\ifmoremath@
\csname newfam\endcsname\mmfam
\edef\mm@{\hexnumber@\mmfam}
\else\fi
\fi
% NFSS-change
% The previous version placed \fam\itfam in \everymath to get text italic
% in math mode. This does not work if this font has not yet been loaded.
% With oldlatex, most text italic sizes are preloaded, but \huge\it may not
% be.
% With the nfss, things may be set up so almost no fonts are preloaded.
% we will put \vdm@it into \everymath later, here we give the definition
% for oldlatex, \fam\itfam as before.
\def\vdm@it{\fam\itfam}
%----------------------------------------------------------------
% The vdm environment
% record whether we were in horizontal mode when entering...
\newif\ifhm@
\def\vdm{\ifhmode\hm@true\else\hm@false\fi
\@changeMathmodeCatcodes\@postUnderPenalty10000\relax}
% after an \end{vdm} the next paragraph is not indented unless a \par
% comes first (if we entered in horizontal mode). This is a bit of a
% kludge!
\def\endvdm{\ifhm@\else
\global\let\par=\@undonoindent
\global\everypar={{\setbox0=\lastbox}\global\everypar={}%
\global\let\par=\@@par}%
\fi}
\def\@undonoindent{\global\everypar={}\global\let\par=\@@par\@@par}
%-----------------------------------------------------------------
% Controlling line and page breaks
% Text within the vdm environment is essentially mathematical in
% nature, so requires special care. Whenever outer vertical mode is
% entered, the \@beginVerticalVDM command should be used. This sets
% up \leftskip, \rightskip, \baselineskip, \lineskip and
% \lineskiplimit to conform with the overall style.
% When entering unrestricted horizontal mode, the \@beginHorizontalVDM
% command should be used. This sets up:
% \leftskip and \rightskip to 0,
% \\ to do line breaking
% ragged right line breaking, with special penalties, and
% enters math mode.
% \@endHorizontalVDM should be called when leaving unrestricted
% horizontal mode.
\def\@beginVerticalVDM{\@changeMargins\@changeBaselineskip}
\def\@beginHorizontalVDM{\@restoreLineSeparator
\@restoreMargins\@raggedRight\noindent$\strut\relax}
\def\@endHorizontalVDM{\relax\strut$}
% \VDMindent is used for \leftskip within VDM, \VDMrindent for
% \rightskip, \VDMbaselineskip for \baselineskip
\newdimen\VDMindent \VDMindent=\parindent
\newdimen\VDMrindent \VDMrindent=\parindent
\def\VDMbaselineskip{\baselineskip}
\def\@changeMargins{\leftskip=\VDMindent \rightskip=\VDMrindent}
\def\@restoreMargins{\advance\hsize by-\leftskip
\advance\hsize by-\rightskip
\leftskip=0pt \rightskip=0pt}
\def\@changeBaselineskip{\baselineskip=\VDMbaselineskip
\lineskip=0pt \lineskiplimit=0pt
% need to alter the size of struts, too
\setbox\strutbox\hbox{\vrule height.7\baselineskip
depth.3\baselineskip width\z@}}
% these are used in externals, records and cases
\def\@changeLineSeparator{\let\\=\cr} % for usr within \halign
\def\@restoreLineSeparator{\let\\=\newline}
\def\@raggedRight{\rightskip=0pt plus 1fil
\hyphenpenalty=-100 \linepenalty=200
\binoppenalty=10000 \relpenalty=10000 \pretolerance=-1}
%------------------------------------------------------------------------
% Font and Character Changes
% make a-zA-Z use the \it family within math mode, and ~ mean \hook.
% Digits 0-9 remain as normal.
\everymath=\expandafter{\the\everymath\vdm@it
\@changeMathmodeCatcodes}
\everydisplay=\expandafter{\the\everydisplay\vdm@it
\@changeMathmodeCatcodes}
\mathcode`\0="0030
\mathcode`\1="0031
\mathcode`\2="0032
\mathcode`\3="0033
\mathcode`\4="0034
\mathcode`\5="0035
\mathcode`\6="0036
\mathcode`\7="0037
\mathcode`\8="0038
\mathcode`\9="0039
% If the user really wants the normal codes, she can call \defaultMathcodes
\def\defaultMathcodes{\let\vdm@it\relax}
% remember the original mathcode of minus sign
\edef\@minuscode{\the\mathcode`\-}
\def\mathminus{\mathcode`\-=\@minuscode }
\def\textminus{\mathcode`\-="002D }
% by default, use text minus
%\textminus
% make a : into punctuation, a - into a letter, and | mean \mid
\ifps@
\def\@changeOtherMathcodes{\mathcode`\:="603A \textminus
\mathcode`\|="327C \mathchardef\Or="32DA % this is a rel to get 5mu spacing
\mathcode`\f="0166} % normal letter spacing
\else
% NFSS-change
% \mathcode`\-="042D changed to \mathcode`\-="002D as we can not rely on
% \itfam being fam 4.
\def\@changeOtherMathcodes{\mathcode`\:="603A \textminus
\mathcode`\|="326A \mathchardef\Or="325F }% this is a rel to get 5mu spacing
\def\relbar{\mathrel{\smash\minus}}% redefine because mathcode of -
% has changed
% alternative underscore
\def\@VDMunderscore{\leavevmode
\kern.06em\vbox{\hrule\@height .2ex\@width .3em}\penalty\@postUnderPenalty
\hskip 0.1em}
% Allow line breaks after an underscore, but not in vdm mode (see
% \vdm). This is so long identifiers can be broken when run
% into paragraphs.
\newcount\@postUnderPenalty \@postUnderPenalty=200
% now require some catcode trickery to enable us to change _ when we want to
{\catcode`\_=\active \catcode`\"=\active
\gdef\@changeGlobalCatcodes{% make _ a normal char
\catcode`\_=\active \let_=\@VDMunderscore}
\gdef\@changeMathmodeCatcodes{%
% make ~ mean \hook, " do text, @ mean subscript
\let~=\hook
\catcode`\@=8
\catcode`\"=\active \let"=\@mathText}
\gdef\underscoreoff{% make _ a normal char
\catcode`\_=\active \let_=\@VDMunderscore}
\gdef\underscoreon{% restore underscore to usual meaning
\catcode`\_=8}
\gdef\@mathText#1"{\hbox{\mathTextFont #1\/}}}
\ifnfss@
\def\mathTextFont{\mathrm}
\else
\def\mathTextFont{\rm}
%----------------------------------------------------------------
% Keywords
\ifx\fmtname\@fmtname
\def\keywordFontBeginSequence{\sf}% user-definable
\else\ifx\fmtname\@psfmtname
\def\keywordFontBeginSequence{\sf}% Helvetica is OK
\else
\def\keywordFontBeginSequence{\bf}% good for SliTeX
\fi\fi
\def\kw#1{\hbox{\keywordFontBeginSequence #1\/}}
\def\makeNewKeyword#1#2{% use \newcommand for extra checks
\newcommand{#1}{\hbox{\keywordFontBeginSequence #2\/}}}
\makeNewKeyword{\nil}{nil}
\makeNewKeyword{\True}{true}
\makeNewKeyword{\true}{true}
\makeNewKeyword{\False}{false}
\makeNewKeyword{\false}{false}
\makeNewKeyword{\rem}{ rem }
\def\where{\par\moveright\VDMindent\hbox{\keywordFontBeginSequence where\/}}
%----------------------------------------------------------------
% monadic operator creation
\def\newMonadicOperator#1#2{\newcommand{#1}{\kw{#2\kern.16667em}\nobreak}}
%----------------------------------------------------------------
% primitive numeric types
% use the AMS fonts for these if possible
\ifams@
\mathchardef\Bool="0\msy@42 % Booleans
\mathchardef\Nat="0\msy@4E % Natural numbers
\def\Nati{\Nat_1} % Positive natural numbers
\mathchardef\Int="0\msy@5A % Integers
\mathchardef\Real="0\msy@52 % Reals
\mathchardef\Rat="0\msy@51 % Rationals
\else\ifmoremath@
\mathchardef\Bool="0\mm@42 % Booleans
\mathchardef\Nat="0\mm@4E % Natural numbers
\def\Nati{\Nat_1} % Positive natural numbers
\mathchardef\Int="0\mm@5A % Integers
\mathchardef\Real="0\mm@52 % Reals
\mathchardef\Rat="0\mm@51 % Rationals
\else
\def\Bool{\hbox{\bf B\/}}
\def\Nat{\hbox{\bf N\/}}
\def\Nati{\hbox{$\hbox{\bf N}_1$}}
\def\Int{\hbox{\bf Z\/}}
\def\Real{\hbox{\bf R\/}}
\def\Rat{\hbox{\bf Q\/}}
\fi\fi
\let\Natone=\Nati % just for an alternative
%----------------------------------------------------------------
% Operations
% The op environment. Within op you can specify args,
% result, etc. which are gathered into registers, and output when the
% op env. ends.
% The optional argument is the operation name
% shorthand for an operation on its own: the vdmop env.
\def\vdmop{\vdm\op} \def\endvdmop{\endop\endvdm}
% registers constructed within an op environment
\newtoks\@operationName
\newbox\@operationNameBox
\newif\ifArgumentListEncountered@
\newtoks\@argumentListTokens
\newtoks\@resultNameAndTypeTokens
\newbox\@externalsBox
\newbox\@preConditionBox
\newbox\@postConditionBox
\newbox\@errConditionBox
\def\op{% clear temporaries, deal with optional arg
\setbox\@operationNameBox=\hbox{}%
\@argumentListTokens={}\ArgumentListEncountered@false
\@resultNameAndTypeTokens={}%
\setbox\@externalsBox=\box\voidb@x
\setbox\@preConditionBox=\box\voidb@x
\setbox\@postConditionBox=\box\voidb@x
\par\preOperationHook
\vskip\preOperationSkip
\@beginVerticalVDM
\@ifnextchar [{\@opname}{}}
% breaking parameters
\newcount\preOperationPenalty \preOperationPenalty=0
\newcount\preExternalPenalty \preExternalPenalty=2000
\newcount\prePreConditionPenalty \prePreConditionPenalty=800
\newcount\prePostConditionPenalty \prePostConditionPenalty=500
\newcount\preErrConditionPenalty \preErrConditionPenalty=500
\newcount\postOperationPenalty \postOperationPenalty=-500
% gaps between bits of operations
\newskip\preOperationSkip \preOperationSkip=2ex plus 0.5ex minus 0.2ex
\newskip\postOperationSkip \postOperationSkip=2ex plus 0.5ex minus 0.2ex
\newskip\postHeaderSkip \postHeaderSkip=.5ex plus .2ex minus .2ex
\newskip\postExternalsSkip \postExternalsSkip=.5ex plus .2ex minus .2ex
\newskip\postPreConditionSkip \postPreConditionSkip=.5ex plus .2ex minus .2ex
\newskip\preErrConditionSkip \preErrConditionSkip=.5ex plus .2ex minus .2ex
\def\endop{% make up operation
% IMPORTANT---don't remove the vskips in this macro
% if you don't want one, set it to 0pt
\vskip 0pt
\@setOperationHeader
\betweenHeaderAndExternalsHook
\vskip\postHeaderSkip
\ifvoid\@externalsBox
\betweenExternalsAndPreConditionHook
\else \moveright\VDMindent\box\@externalsBox
\betweenExternalsAndPreConditionHook
\vskip\postExternalsSkip
\ifvoid\@preConditionBox
\betweenPreAndPostConditionHook
\else \moveright\VDMindent\box\@preConditionBox
\betweenPreAndPostConditionHook
\vskip\postPreConditionSkip
\ifvoid\@postConditionBox
\betweenPostAndErrHook
\else \moveright\VDMindent\box\@postConditionBox
\betweenPostAndErrConditionHook
\ifvoid\@errConditionBox
\else \vskip\preErrConditionSkip
\moveright\VDMindent\box\@errConditionBox
\postOperationHook
\vskip\postOperationSkip}
% hooks for user-defined expansion
% TeX is in outer vertical mode when these are called.
% ALWAYS leave TeX in vertical mode after these macros have been called
\def\preOperationHook{\penalty\preOperationPenalty }
\def\betweenHeaderAndExternalsHook{\penalty\preExternalPenalty }
\def\betweenExternalsAndPreConditionHook{\penalty\prePreConditionPenalty }
\def\betweenPreAndPostConditionHook{\penalty\prePostConditionPenalty }
\def\betweenPostAndErrConditionHook{\penalty\preErrConditionPenalty }
\def\postOperationHook{\penalty\postOperationPenalty }
% combine the operation name, argument list and result
\def\@setOperationHeader{%
\moveright\VDMindent\vtop{%
\ifArgumentListEncountered@
\setbox\@operationNameBox=%
\hbox{\unhbox\@operationNameBox$($}\fi
\hangindent=\wd\@operationNameBox \hangafter=1
\noindent\kern-.05em\box\@operationNameBox
\@beginHorizontalVDM
\ifArgumentListEncountered@\the\@argumentListTokens)\fi
\ \the\@resultNameAndTypeTokens
\@endHorizontalVDM}}
% set the operation name
% \opname{name-of-operation}
\def\opname#1{\@opname[#1]}
\def\@opname[#1]{\@operationName={#1}%
\global\setbox\@operationNameBox=\hbox{$\relax#1$\ }}
% set up the argument list
% \args{ argument \\ argument \\ argument... } where \\ forces a line break
% This is also used in the fn environment
\def\args{\global\ArgumentListEncountered@true \global\@argumentListTokens=}
% result name and type
\def\res{\global\@resultNameAndTypeTokens=}
% externals list
% An external list could be either very long or very short, so we provide
% two forms. One is the short \ext{..} command, the other is the externals
% environment.
% Externals are always separated by \\
% we have to mess a little to get the catcode of : right
\def\ext{\bgroup\@makeColonActive\@ext}
\def\@ext#1{\externals#1\endexternals\egroup}
\def\externals{\global\setbox\@externalsBox=%
\@beginIndentedPara{\hsize}{ext }{\@setUpExternals}}
\def\endexternals{\@endIndentedPara{\@endAlignment}}
\def\@setUpExternals{\@makeColonActive\@changeLineSeparator\@beginAlignment}
% more catcode trickery for :
{\catcode`\:=\active
\gdef\@makeColonActive{\catcode`\:=\active \let:=&}}
% the \expandafters are necessary because TeX doesn't expand
% \halign specs when scanning for # and &
\def\@beginAlignment{\expandafter\halign\expandafter\bgroup
\the\@extAlign\strut\enspace&:\enspace$##$\hfil\cr}
\def\@endAlignment{\crcr\egroup}
% the user can decide on the exact alignment of the field names
\newtoks\@extAlign
\def\leftExternals{\@extAlign={$##$\hfil}}
\def\rightExternals{\@extAlign={\hfil$##$}}
\leftExternals
\makeNewKeyword{\Rd}{rd } \makeNewKeyword{\Wr}{wr }
% pre-condition, post-condition and err-condition
% once again we provide short forms \pre, \post, \err and environments
% precond, postcond and errcond
\def\pre#1{\precond#1\endprecond}
\def\precond{\global\setbox\@preConditionBox=%
\@beginMathIndentedPara{\hsize}{pre }}
\def\endprecond{\@endMathIndentedPara}
\def\post#1{\postcond#1\endpostcond}
\def\postcond{\global\setbox\@postConditionBox=%
\@beginMathIndentedPara{\hsize}{post }}
\def\endpostcond{\@endMathIndentedPara}
\def\err#1{\errcond#1\enderrcond}
\def\errcond{\global\setbox\@errConditionBox=%
\@beginMathIndentedPara{\hsize}{errs }}
\def\enderrcond{\@endMathIndentedPara}
%----------------------------------------------------------------
% Box man\oe uvres
% Here's where all the tricky box manipulation commands go
% \@beginIndentedPara begins construction of a \hbox of width #1
% which contains keyword #2 to the left of a para in a vtop.
% #3 is evaluated within the inner vtop.
% endIndentedPara closes the box off; its arg. is evaluated just
% before closing the box.
\def\@beginIndentedPara#1#2#3{\hbox to #1\bgroup \setbox0=\kw{#2}%
\copy0 \strut \vtop\bgroup \advance\hsize by -\wd0 #3}
\def\@endIndentedPara#1{\strut#1\egroup\hss\egroup}
% \@beginMathIndentedPara places the para in vdm mode
\def\@beginMathIndentedPara#1#2{\@beginIndentedPara{#1}{#2}%
{\@beginHorizontalVDM}}
\def\@endMathIndentedPara{\@endIndentedPara{\@endHorizontalVDM}}
% \@belowAndIndent#1#2 places #2 in a vbox below and to the right of #1
\def\@belowAndIndent#1#2{#1\hfil\break
\@beginMathIndentedPara{\hsize}{\qquad}#2\@endMathIndentedPara}
% \@mathIndentedPara does the whole thing
\def\@mathIndentedPara#1#2#3{\@beginMathIndentedPara{#1}{#2}#3%
\@endMathIndentedPara}
%----------------------------------------------------------------
% Constructions
% Here are all the standard constructions.
% The only tricky one is \cases.
% Those that construct a box must be made to make that box of 0 width,
% and force a line break immediately afterwards.
% \If mm-exp \Then mm-exp \Else mm-exp \Fi
% multi-line indented if-then-else
\def\If#1\Then#2\Else#3\Fi{\vtop{%
\@mathIndentedPara{0pt}{if }{#1}%
\@mathIndentedPara{0pt}{then }{#2}%
\@mathIndentedPara{0pt}{else }{#3}}}
% \SIf mm-exp \Then mm-exp \Else mm-exp \Fi
% single line if-then-else
\def\SIf#1\Then#2\Else#3\Fi{\hbox to 0pt{\vtop{\@beginHorizontalVDM
\kw{if }\nobreak#1\penalty0\hskip 0.5em
\kw{then }\nobreak#2\penalty-100\hskip 0.5em % break here OK
\kw{else }\nobreak#3\@endHorizontalVDM}\hss}}
% \Let mm-exp \In mm-exp2
% multi-line let..in ; mm-exp2 is `curried'
\def\Let#1\In{\vtop{%
\@mathIndentedPara{0pt}{let }{#1\hskip 0.5em\kw{in}}}\hfil\break}
% \SLet mm-exp \In mm-exp
% single-line let..in
\def\SLet#1\In#2{\hbox to 0pt{\vtop{\@beginHorizontalVDM
\kw{let }\nobreak#1\hskip 0.5em
\kw{in }\penalty-100 #2\@endHorizontalVDM}\hss}}
% multi-line cases
% \Cases{ selecting-mm-exp }
% from-case1 & to-case1 \\
% from-case2 & to-case2 \\
% ...
% from-casen & to-casen
% \Otherwise{ mm-exp }
% \Endcases[optional text for the rest of the line]
\newif\ifOtherwiseEncountered@
\newtoks\@OtherwiseTokens
\def\Cases#1{\hbox to 0pt\bgroup \vtop\bgroup
\@mathIndentedPara{\hsize}{cases }{\strut
#1\hskip 0.5em\strut\kw{of}}%
\bgroup % we might be in a nested case, so we have to
% save the \Otherwise bits we might lose
\OtherwiseEncountered@false \@changeLineSeparator
\@beginCasesAlignment}
% the user can decide on the exact alignment
\newtoks\@casesDef
\def\leftCases{\@casesDef={$##$\hfil}}
\def\rightCases{\@casesDef={\hfil$##$}}
\rightCases
% the \expandafters are necessary because TeX doesn't expand
% \halign specs when scanning for # and &
\def\@beginCasesAlignment{\expandafter\halign\expandafter\bgroup
\the\@casesDef&$\,\rightarrow##$\hfil\cr}
\def\Otherwise{\global\OtherwiseEncountered@true \global\@OtherwiseTokens=}
\let\Others=\Otherwise
\def\Endcases{\@endCasesAlignment \@setOtherwise \egroup \@setEndcases}
\def\@endCasesAlignment{\crcr\egroup}
\def\@setOtherwise{\ifOtherwiseEncountered@ % have an otherwise clause
\@mathIndentedPara{\hsize}{others }{%
\strut\the\@OtherwiseTokens\strut}
\fi}
% must test for the optional arg to follow the end
\def\@setEndcases{\noindent
\strut\kw{end}\@ifnextchar [{\@unbracket}{\@finalCaseEnd}}
\def\@unbracket[#1]{$#1$\@finalCaseEnd}
\def\@finalCaseEnd{\egroup\hss\egroup}%\hfil\break
%----------------------------------------------------------------
% special symbols
% defined as
\ifps@
\def\DEF{\raise.5ex
\hbox{\footnotesize\underline{$\mathchar"3\cmsy@34$}}}% a \triangle
\else
\def\DEF{\raise.5ex
\hbox{\footnotesize\underline{$\mathchar"3234$}}}% a \triangle
% cross product
\let\x=\times
% logical connectives
\def\Iff{\penalty-50\mskip 7mu plus 2mu minus 2mu
\Leftrightarrow\mskip 7mu plus 2mu minus 2mu}
\let\iff=\Iff
\def\Implies{\penalty-35\mskip 6mu plus 2mu minus 1mu \Rightarrow
\mskip 6mu plus 2mu minus 1mu}
\let\implies=\Implies
% see changeOtherMathcodes for \Or
\let\And=\land
\let\@and=\and
\def\and{\ifmmode\And\else\@and\fi}
% use \neg for logical not, or
\def\Not{\neg\,}
% quantification
\ifps@
\mathchardef\Exists="0224
\mathchardef\Forall="0222
\mathchardef\suchthat="22D7
\else
\mathchardef\Exists="0239
\mathchardef\Forall="0238
\mathchardef\suchthat="2201
\def\exists{\@ifstar{\@splitExists}{\@normalExists}}
\ifams@
\mathchardef\@nexists="0\msy@40 % crossed out existential quantifier
\else\ifps@
\def\@nexists{\hbox to 0pt{\kern0.2ex\raise0.1ex\hbox{/}\hss}\Exists}
\else
\def\@nexists{\hbox to 0pt{\raise0.15ex\hbox{/}\hss}\Exists}
\fi\fi
\def\nexists{\@ifstar{\@splitNExists}{\@normalNExists}}
\def\forall{\@ifstar{\@splitForall}{\@normalForall}}
\def\unique{\@ifstar{\@splitUnique}{\@normalUnique}}
\def\uniqueval{\@ifstar{\@splitUniqueval}{\@normalUniqueval}}
\def\@normalExists#1#2{{\Exists#1}\suchthat #2}
\def\@normalNExists#1#2{{\@nexists#1}\suchthat #2}
\def\@normalForall#1#2{{\Forall#1}\suchthat #2}
\def\@normalUnique#1#2{{\Exists!\,#1}\suchthat #2}
\def\@normalUniqueval#1#2{{\iota\,#1}\suchthat #2}
\def\@splitExists#1{\@belowAndIndent{\Exists#1\suchthat}}
\def\@splitNExists#1{\@belowAndIndent{\@nexists#1\suchthat}}
\def\@splitForall#1{\@belowAndIndent{\Forall#1\suchthat}}
\def\@splitUnique#1{\@belowAndIndent{\Exists!\,#1\suchthat}}
\def\@splitUniqueval#1{\@belowAndIndent{\iota\,#1\suchthat}}
% sequents
\let\Tstlp=\vdash
\def\sequent{\@ifstar{\@splitSequent}{\@normalSequent}}
\def\@normalSequent#1#2{{#1}\:\Tstlp\: #2}
\def\@splitSequent#1{\@belowAndIndent{#1\;\Tstlp}}
% strachey brackets
% (see TeXbook, p.437)
\ifmoremath@
\def\term#1{\thinspace\mathchar"4\mm@ D2\relax#1\mathchar"5\mm@ D4\thinspace}
\else
\def\term#1{[\mkern-\thinmuskip[#1\relax]\mkern-\thinmuskip]}
% function composition
\let\compf=\circ
%----------------------------------------------------------------
% function environment
% This environment is similar to the op environment, but is used for
% function definition.
% The mandatory first parameter is the name of the function, the
% second is the argument list.
% The *-form simply doesn't force the parentheses round the argument list
\def\fn{\parens@true\@beginVDMfunction}
\@namedef{fn*}{\parens@false\@beginVDMfunction}
\@namedef{endfn*}{\endfn}
% short form
\def\vdmfn{\vdm\parens@true \@beginVDMfunction}
\def\endvdmfn{\endfn\endvdm}
\@namedef{vdmfn*}{\vdm\parens@false \@beginVDMfunction}
\@namedef{endvdmfn*}{\endfn\endvdm}
% registers used within the fn environment
\newtoks\@fnName
\newbox\@fnNameBox
\newif\ifsignatureEncountered@
\newtoks\@signatureTokens
\newbox\@fnDefnBox
\newif\ifparens@
\def\@beginVDMfunction#1#2{%
\@fnName={#1}%
\setbox\@fnNameBox=\hbox{$#1$}%
\setbox\@preConditionBox=\box\voidb@x % for people who want to do
\setbox\@postConditionBox=\box\voidb@x% implicit defns
\@signatureTokens={}\signatureEncountered@false
\ifparens@
\@argumentListTokens={(#2)}%
\else
\@argumentListTokens={#2}%
\par\preFunctionHook
\vskip\preFunctionSkip
\@beginVerticalVDM
\@beginFnDefn}
% read in a signature
\def\signature{\global\signatureEncountered@true \global\@signatureTokens=}
\def\@beginFnDefn{\global\setbox\@fnDefnBox=\vtop\bgroup
\hangindent=2em \hangafter=1 \@beginHorizontalVDM
\advance\hsize by-2em % this fools vboxes within the
% function body about the hanging indent...yuk.
% If you change the size of the indent, change the
% corresponding line in \endfn.
\copy\@fnNameBox \the\@argumentListTokens
\quad\DEF\penalty-100\quad }
\newskip\preFunctionSkip \preFunctionSkip=2ex plus .5ex minus .2ex
\newskip\postFunctionSkip \postFunctionSkip=2ex plus .5ex minus .2ex
\newskip\betweenSignatureAndBodySkip
\betweenSignatureAndBodySkip=1.2ex plus .3ex minus .2ex
\newskip\betweenFunctionAndPreSkip
\betweenFunctionAndPreSkip=1.2ex plus .3ex minus .2ex
\def\endfn{%
\advance\hsize by 2em% matches the dirty \advance in \@beginFnDefn
\@endHorizontalVDM
\egroup % this ends the vtop we started in \@beginFnDefn
\ifsignatureEncountered@
\setbox0=\hbox{\unhbox\@fnNameBox$\;\mathpunct:\,$}%
\dimen255=\wd0 \noindent \box0
\vtop{\advance\hsize by-\dimen255 \@beginHorizontalVDM
\the\@signatureTokens \@endHorizontalVDM}\par
\betweenSignatureAndBodyHook
\vskip\betweenSignatureAndBodySkip
\moveright\VDMindent\box\@fnDefnBox\,
\ifvoid\@preConditionBox
\betweenPreAndPostConditionHook
\vskip\postFunctionSkip
\else \betweenFunctionAndPreHook
\vskip\betweenFunctionAndPreSkip
\moveright\VDMindent\box\@preConditionBox
\betweenPreAndPostConditionHook
\vskip\postPreConditionSkip
\ifvoid\@postConditionBox
\postFunctionHook
\else \moveright\VDMindent\box\@postConditionBox
\postFunctionHook
\vskip\postOperationSkip
\fi}
\newcount\preFunctionPenalty \preFunctionPenalty=0
\newcount\betweenSignatureAndBodyPenalty
\betweenSignatureAndBodyPenalty=10000
\newcount\betweenFunctionAndPrePenalty \betweenFunctionAndPrePenalty=1000
\newcount\postFunctionPenalty \postFunctionPenalty=-500
% These are called in outer vertical mode---they must also exit in this mode
\def\preFunctionHook{\penalty\preFunctionPenalty }
\def\betweenSignatureAndBodyHook{\penalty\betweenSignatureAndBodyPenalty }
\def\betweenFunctionAndPreHook{\penalty\betweenFunctionAndPrePenalty }
\def\postFunctionHook{\penalty\postFunctionPenalty }
% other function-related things
% function arrow
\def\to{\penalty-100\rightarrow}
% explicit lamdba function
\def\LambdaFn{\@ifstar{\@splitLambdaFn}{\@normalLambdaFn}}
\def\@normalLambdaFn#1#2{{\lambda#1}\suchthat#2}
\def\@splitLambdaFn#1#2{% place body in a separate box below and to the right
{\lambda#1}\suchthat\hfil\break
\@mathIndentedPara{\hsize}{\qquad}{#2}}
%----------------------------------------------------------------
% Optional fields
\def\Opt#1{\big[#1\big]}
%----------------------------------------------------------------
% Sets
% new set type
\def\setof#1{#1-\kw{set}}
% set enumeration
\def\set#1{\{#1\}}
% empty set
\def\emptyset{\{\,\}}
% usual LaTeX operators apply: \in \notin \subset \subseteq
\let\inter=\cap \let\intersection=\inter
\let\Inter=\bigcap \let\Intersection=\Inter
\let\union=\cup
\let\Union=\bigcup
\ifps@
\mathchardef\minus="222D
\else
\mathchardef\minus="2200
\def\diff{\minus} \let\difference=\diff
\newMonadicOperator{\card}{card}
\newMonadicOperator{\Min}{min}
\newMonadicOperator{\Max}{max}
\newMonadicOperator{\abs}{abs}
%----------------------------------------------------------------
% Map type
% new map type
\def\mapof#1#2{#1\buildrel m\over\longrightarrow#2}
% one-one map
\def\mapinto#1#2{#1\buildrel m\over\longleftrightarrow#2}
% map enumeration
\def\map#1{\{#1\}}
% empty map
\def\emptymap{\{\,\}}
% map operators
% use \mapsto for |->
% overwrite
\def\owr{\dagger}
\ifmoremath@
\mathchardef\dres="2\mm@ B2
\mathchardef\rres="2\mm@ B3 % the right hand version
\else
\let\dres=\lhd
\let\rres=\rhd
% domain subtraction
\ifmoremath@
\mathchardef\dsub="2\mm@ F8
% what a horror -- some people will insist on these daft symbols...
\else\ifps@
\def\dsub{\mathbin{\hbox{$\rlap{$\mathord\minus$}\mkern-3mu\hbox{$\dres$}$}}}
\else
\def\dsub{\mathbin{\hbox{$\rlap{$\mathord\minus$}\mkern-1.5mu
\lower.1ex\hbox{$\dres$}$}}}
\fi\fi
% range subtraction
\ifmoremath@
\mathchardef\rsub="2\mm@ F9
\else\ifps@
\def\rsub{\mathbin{\hbox{$\rlap{$\mathord\minus$}\mkern-1.5mu\rres$}}}
\else
\def\rsub{\mathbin{\hbox{$\rlap{$\mathord\minus$}\mkern-1.5mu
\lower.1ex\hbox{$\rres$}$}}}
\fi\fi
\newMonadicOperator{\dom}{dom}
\newMonadicOperator{\rng}{rng}
\newMonadicOperator{\merge}{merge}
%----------------------------------------------------------------
% Sequences
% new type
\def\seqof#1{#1^*}
% non-empty sequence
\def\neseqof#1{#1^+}
% enumeration
\def\seq#1{[#1]}
% empty sequence
\def\emptyseq{[\,]}
\newMonadicOperator{\len}{len}
\newMonadicOperator{\hd}{hd}
\newMonadicOperator{\tl}{tl}
\newMonadicOperator{\elems}{elems}
\newMonadicOperator{\inds}{inds}
\def\cons#1{\kw{cons}\nobreak(#1)}
% sequence concatenation
\ifmoremath@
\mathchardef\sconc="2\mm@63
\else\ifams@
\def\sconc{\mathbin{\hbox{\raise1ex\hbox{$\mathchar"2\msy@79$}}}}
\else
% this is truly yukky
\def\sconc{\mathbin{\hbox{\raise1ex\hbox{$\frown$}\kern-0.47em
\raise0.2ex\hbox{\it\char"12}}}}
\fi\fi
% distributed concatenation
\newMonadicOperator{\Conc}{dconc}
%----------------------------------------------------------------
% type equation
\newtoks\@typeName
\def\type#1#2{{\@typeName{#1} \preTypeHook \vskip\preTypeSkip
\@beginVerticalVDM
\moveright\VDMindent\vtop{\@beginHorizontalVDM #1=#2%
\@endHorizontalVDM}
\postTypeHook \vskip\postTypeSkip}}
% restricted type (has invariant)
\def\rtype#1#2#3{{\@typeName{#1} \preTypeHook \vskip\preTypeSkip
\@beginVerticalVDM
\moveright\VDMindent\vtop{\@beginHorizontalVDM #1=#2%
\@endHorizontalVDM}
\vskip\betweenTypeAndInvSkip
\moveright\VDMindent\@mathIndentedPara{\hsize}{inv }{#3}%
\postTypeHook \vskip\postTypeSkip}}
% initialised type
\def\ritype#1#2#3#4{{\@typeName{#1} \preTypeHook \vskip\preTypeSkip
\@beginVerticalVDM
\moveright\VDMindent\vtop{\@beginHorizontalVDM #1=#2%
\@endHorizontalVDM}
\vskip\betweenTypeAndInvSkip
\moveright\VDMindent\@mathIndentedPara{\hsize}{inv }{#3}%
\vskip\betweenInvAndInitSkip
\moveright\VDMindent\@mathIndentedPara{\hsize}{init }{#4}%
\postTypeHook \vskip\postTypeSkip}}
\def\preTypeHook{} \def\postTypeHook{}
\newskip\preTypeSkip \preTypeSkip=1.2ex plus .5ex minus .3ex
\newskip\postTypeSkip \postTypeSkip=1.2ex plus .5ex minus .3ex
\newskip\betweenTypeAndInvSkip
\betweenTypeAndInvSkip=.5ex plus .3ex minus .2ex
\newskip\betweenInvAndInitSkip
\betweenInvAndInitSkip=.5ex plus .3ex minus .2ex
%----------------------------------------------------------------
% Composite Objects
% literal composition; we have a compose and a composite env.
% single line compose
\@namedef{composite*}#1{\kw{compose }$\relax#1\relax$\kw{ of }$\relax}
\@namedef{endcomposite*}{\relax$\kw{ end}}
% multiple line version
\def\composite#1{\bgroup\vskip\preCompositeSkip
\@beginVerticalVDM
\moveright\VDMindent\vtop\bgroup
\@beginHorizontalVDM
\kw{compose }#1\kw{ of}%
\@endHorizontalVDM
\@makeColonActive\@changeLineSeparator
\expandafter\halign\expandafter\bgroup\expandafter\qquad
\the\@recordAlign\strut\enspace&:\enspace$##$\hfil\cr}
\def\endcomposite{\crcr\egroup % closes \halign
\kw{end}\egroup % ends the \vtop
\vskip\postCompositeSkip\egroup}
\def\scompose#1#2{\@nameuse{composite*}{#1}{#2}\@nameuse{endcomposite*}}
\newskip\preCompositeSkip \preCompositeSkip=1.2ex plus .5ex minus .3ex
\newskip\postCompositeSkip \postCompositeSkip=1.2ex plus .5ex minus .3ex
% record composites; likewise we have a short and a long form
\newtoks\@recordName
\def\record#1{%
\InvEncountered@false \InitEncountered@false
\@invTokens={}\@initTokens={}
\@recordName{#1}
\par\preRecordHook
\vskip\preRecordSkip
\@beginVerticalVDM
\moveright\VDMindent\hbox\bgroup
\setbox0=\hbox{$#1$\enspace::\enspace}%
\@makeColonActive\@changeLineSeparator
\advance\hsize by-\wd0 \box0
\@restoreMargins
% the \expandafters are necessary because TeX doesn't expand
% \halign specs when scanning for # and &
\vtop\bgroup\expandafter\halign\expandafter\bgroup
\the\@recordAlign\strut\enspace&:\enspace$##$\hfil\cr}
\def\endrecord{\crcr\egroup% closes halign
\egroup% closes vtop
\egroup% closes hbox
\ifInvEncountered@
\betweenRecordAndInvHook
\vskip\betweenRecordAndInvSkip
\moveright\VDMindent\@mathIndentedPara{\hsize}{inv }{%
\the\@invTokens}
\fi
\ifInitEncountered@
\betweenInvAndInitHook
\vskip\betweenInvAndInitSkip
\moveright\VDMindent\@mathIndentedPara{\hsize}{init }{%
\the\@initTokens}
\fi
\par\postRecordHook
\vskip\postRecordSkip}
\def\inv{\global\InvEncountered@true \global\@invTokens=}
\def\init{\global\InitEncountered@true \global\@initTokens=}
\newif\ifInvEncountered@
\newif\ifInitEncountered@
\newtoks\@invTokens
\newtoks\@initTokens
\def\betweenRecordAndInvHook{}
\def\betweenInvAndInitHook{}
\newskip\betweenRecordAndInvSkip
\betweenRecordAndInvSkip=0.5ex plus 0.2ex minus 0.1ex
\newskip\betweenInvAndInitSkip
\betweenInvAndInitSkip=0.5ex plus 0.2ex minus 0.1ex
% the user can decide on the exact alignment of the field names
\newtoks\@recordAlign
\def\leftRecord{\@recordAlign={$##$\hfil}}
\def\rightRecord{\@recordAlign={\hfil$##$}}
\rightRecord
% more catcode trickery
\def\defrecord{\bgroup\@makeColonActive\@defrecord}
\def\@defrecord#1#2{\record{#1}#2\endrecord\egroup}
\newskip\preRecordSkip \preRecordSkip=.75ex plus .3ex minus .2ex
\newskip\postRecordSkip \postRecordSkip=.75ex plus .3ex minus .2ex
\newcount\preRecordPenalty \preRecordPenalty=0
\newcount\postRecordPenalty \postRecordPenalty=-100
\def\preRecordHook{\penalty\preRecordPenalty }
\def\postRecordHook{\penalty\postRecordPenalty }
% \chg: mu function on composites
\def\chg#1#2#3{\mu(#1,#2\mapsto#3)}
%----------------------------------------------------------------
% Hooks
% hooked identifiers --- these are taken from the TeXbook, p.357, 359
\ifps@
\def\leftharpoonupfill{$\m@th \mathord\leftharpoonup \mkern-6mu
\cleaders\hbox{$\mkern-2mu \mathchar"0\cmsy@00 \mkern-2mu$}\hfill
\mkern-6mu \mathchar"0\cmsy@00$} % p.357, \leftarrowfill
\else
\def\leftharpoonupfill{$\m@th \mathord\leftharpoonup \mkern-6mu
\cleaders\hbox{$\mkern-2mu \mathord\minus \mkern-2mu$}\hfill
\mkern-6mu \mathord\minus$} % p.357, \leftarrowfill
\def\overleftharpoonup#1{{%
\boxmaxdepth=\maxdimen % this fixes Lamport's figures, but isn't necessary
% for versions after 15 Dec 87
\vbox{\ialign{##\crcr % p.359, \overleftarrow
\leftharpoonupfill\crcr\noalign{\kern-\p@\nointerlineskip}
$\hfil\displaystyle{#1}\hfil$\crcr}}}}
\let\hook=\overleftharpoonup % c'est simple comme bonjour
%-----------------------------------------------------------------
% General formula environment, a bit like \[ \] but is
% indented to \VDMindent and will take \\
\def\form#1{\formula #1\endformula}
\def\formula{\par\preFormulaHook
\vskip\preFormulaSkip
\@beginVerticalVDM
\bgroup
\moveright\VDMindent\vtop\bgroup\@beginHorizontalVDM}
\def\endformula{\@endHorizontalVDM\egroup % ends the vtop
\egroup % ends the overall group
\par\postFormulaHook
\vskip\postFormulaSkip}
\newskip\preFormulaSkip \preFormulaSkip=1.2ex plus .5ex minus .3ex
\newskip\postFormulaSkip \postFormulaSkip=1.2ex plus .5ex minus .3ex
\newcount\preFormulaPenalty \preFormulaPenalty=0
\newcount\postFormulaPenalty \postFormulaPenalty=-100
\def\preFormulaHook{\penalty\preFormulaPenalty }
\def\postFormulaHook{\penalty\postFormulaPenalty }
%----------------------------------------------------------------
% Formula within a box, when width is unknown
% equivalent to \parbox[t]{\hsize}{\@beginHorizontalVDM
% ...\@endHorizontalVDM}
\def\formbox{\vtop\bgroup\@beginHorizontalVDM}
\def\endformbox{\strut\@endHorizontalVDM\egroup}
%----------------------------------------------------------------
% special font for constants
\def\constantFont{\sc}
\def\const#1{\hbox{\constantFont{#1}\/}}
%----------------------------------------------------------------
% line break and indent
\def\T#1{\\\hbox to #1em{}}
%----------------------------------------------------------------
% line break and push line after to RHS
\def\R{\\\hspace*{\fill}}
%----------------------------------------------------------------
% Proofs
% a proof environment for typesetting proofs in the "natural
% deduction" style.
\newdimen\ProofIndent \ProofIndent=\VDMindent
\newdimen\ProofNumberWidth \ProofNumberWidth=\parindent
\def\proof{\par\preProofHook
\vskip\preProofSkip
\let\&=\@proofLine
\moveright\ProofIndent\vtop\bgroup
\@indentLevel=1
\advance\linewidth by-\ProofIndent
\begin{tabbing}%
\hbox to\ProofNumberWidth{}\=\kill} % template line
\def\endproof{\end{tabbing}\advance\linewidth by\ProofIndent
\egroup % ends the \vtop
\par\postProofHook
\vskip\postProofSkip}
\newskip\preProofSkip \preProofSkip=1.2ex plus .5ex minus .3ex
\newskip\postProofSkip \postProofSkip=1.2ex plus .5ex minus .3ex
\newcount\preProofPenalty \preProofPenalty=-100
\newcount\postProofPenalty \postProofPenalty=0
\def\preProofHook{\penalty\preProofPenalty }
\def\postProofHook{\penalty\postProofPenalty }
\def\From{\@indentProof\kw{from }\=%
\global\advance\@indentLevel by 1
\@enterMathMode}
\def\Infer{\global\advance\@indentLevel by-1
\@indentProof\kw{infer }\@enterMathMode}
\def\@proofLine{\@indentProof\@enterMathMode}
\def\by{\`}
\newcount\@indentLevel
\newcount\@indentCount
\def\@indentProof{% do \>, \@indentLevel times
\global\@indentCount=\@indentLevel
\@gloop \>\global\advance\@indentCount by-1
\ifnum\@indentCount>0
\repeat}
% need special loop macros that works in across boxes
\def\@gloop#1\repeat{\gdef\@body{#1}\@giterate}
\def\@giterate{\@body \global\let\@gloopNext=\@giterate
\else \global\let\@gloopNext=\relax \fi \@gloopNext}
% this enters math mode and sets the LaTeX macros \@stopfield up
% to exit math mode
\def\@enterMathMode{\def\@stopfield{$\egroup}$}
%----------------------------------------------------------------
\def\VDMauthor{M.Wolczko,
CS Dept.,
Univ. of Manchester, UK.
mario@cs.man.ac.uk
uknet!man.cs!mario}
\def\VDMversion{vdm3.0}
\typeout{BSI VDM style option <1 May 1992>}
%----------------------------------------------------------------
% Global changes
% All things that have to be invoked before the user's stuff appears
% should go here.
% by default the math spacing and changes to @ and _ apply everywhere
\@changeOtherMathcodes \@changeGlobalCatcodes
%-------------------the end--------------------------------------
\endinput
% Summary of penalties
% Penalties in vertical mode
% \preOperationPenalty before an op begins
% \preExternalPenalty between the header and externals of an op
% \prePreConditionPenalty before the precondition
% \prePostConditionPenalty before the postcondition
% \postOperationPenalty at the end of an op
% \preFunctionPenalty before a fn begins
% \betweenSignatureAndBodyPenalty -guess
% \postFunctionPenalty after a fn ends
% \preRecordPenalty before a record
% \postRecordPenalty after a record
% etc for formula, proof
% Penalties in horizontal mode in boxes
% \linepenalty 101 \@raggedRight
% `if mm-exp ^ then..' 0 \SIf
% `if ... then mm-exp ^ else' -100 \SIf
% `let mm-exp in ^ ...' -100 \SLet
% `map mm-exp ^ to ...' -50 \map
% ^\iff -50 \iff
% ^\implies -35 \implies
% func(args) \DEF^ -100 \begin{fn}
% \binoppenalty 10000
% \relpenalty 10000
% \hyphenpenalty -100 \suchthat
% ^\to -100 \to
% _^ 100 \@VDMunderscore